{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 问题：什么是猴子补丁？\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "collapsed": true
   },
   "source": [
    "面试官想从这道题中考察面试人什么？\n",
    "如果您从事的是大型项目，则很可能会遇到一些情况，即您想更改或改进第三方库的行为。这个时候，“猴子补丁” 可能就能派上用场。\n",
    "\n",
    "答案\n",
    "在运行时修改类或模块，而不改变源码。\n",
    "\n",
    "拓展\n",
    "我们继续上面讲到的那个鸭子类型的例子。\n",
    "\n",
    ">>> obj1[:]\n",
    "['a', 'b', 'c', 'd', 'e']\n",
    ">>> from random import shuffle\n",
    ">>> shuffle(obj1)\n",
    "Traceback (most recent call last):\n",
    "~/.virtualenvs/p3_env/lib/python3.7/random.py in shuffle(self, x, random)\n",
    "    276                 # pick an element in x[:i+1] with which to exchange x[i]\n",
    "    277                 j = randbelow(i+1)\n",
    "--> 278                 x[i], x[j] = x[j], x[i]\n",
    "    279         else:\n",
    "    280             _int = int\n",
    "TypeError: 'LikeSequence' object does not support item assignment\n",
    "我们尝试去调用 shuffle 来打乱新序列的顺序，但是这么做会出现异常，因为’LikeSequence’对象不支持__setitem__，那么下面这么做，看看会发生什么：\n",
    "\n",
    ">>> def set_item(l, position, item):\n",
    "...    l._components[position] = item\n",
    "...\n",
    ">>> LikeSequence.__setitem__ = set_item\n",
    ">>> shuffle(obj1)\n",
    ">>> obj1[:]\n",
    "['b', 'd', 'a', 'e', 'c']\n",
    "像上面这样就是一种猴子补丁（monkey patch），我们可以先去创建实例然后再给类去定义方法。它允许我们在运行时修改或扩展库，模块，类或方法的行为，而无需实际修改源代码。\n",
    "\n",
    "猴子补丁使用的主要场景：\n",
    "\n",
    "在运行时扩展或修改第三方或内置库或方法的行为，而无需触及原始代码；\n",
    "在测试期间模拟库，模块，类或任何对象的行为；\n",
    "如果我们没有足够的时间或资源为原始软件推出适当的修复程序，则可以快速解决一些问题。\n",
    "但是，猴子补丁需要非常谨慎地使用，尤其是在生产软件中使用时，一些原因是：\n",
    "\n",
    "如果我们通过猴子修补来更改方法的行为，则该方法将不再具有记录的方式。因此，除非每个客户端或用户都知道此更改，否则可能导致他们的代码行为异常；\n",
    "这使得解决问题变得更加困难；\n",
    "如果我们在一个模块中对猴子打补丁，而在应用补丁后在另一个模块中使用相同的方法，那么第二个模块也会看到猴子打补丁的方法，而不是原始版本。这可能会导致有害的错误。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}